<template>
  <el-dialog
    v-model="visible"
    title="移动文件"
    width="600px"
    @close="handleClose"
  >
    <div class="move-dialog-content">
      <!-- 待移动文件列表 -->
      <div class="files-section">
        <h4>待移动的文件/文件夹 ({{ filesToMove.length }}个)</h4>
        <div class="files-list">
          <div
            v-for="file in filesToMove"
            :key="file.id"
            class="file-item"
          >
            <el-icon class="file-icon">
              <Folder v-if="file.isFolder === 1" />
              <Document v-else />
            </el-icon>
            <span class="file-name">{{ file.fileName }}</span>
            <span class="file-size" v-if="file.isFolder === 0">
              {{ formatFileSize(file.fileSize) }}
            </span>
          </div>
        </div>
      </div>

      <!-- 目标位置选择 -->
      <div class="target-section">
        <h4>选择目标位置</h4>
        <FolderSelector
          v-model="targetFolderId"
          :exclude-ids="excludeFolderIds"
          @change="handleFolderChange"
        />
      </div>

      <!-- 移动选项 -->
      <div class="options-section">
        <el-checkbox v-model="moveOptions.keepOriginalPath">
          保持原有目录结构
        </el-checkbox>
        <el-checkbox v-model="moveOptions.overwriteExisting">
          覆盖同名文件
        </el-checkbox>
      </div>

      <!-- 移动预览 -->
      <div v-if="targetFolder" class="preview-section">
        <h4>移动预览</h4>
        <div class="move-preview">
          <div class="preview-item" v-for="file in filesToMove" :key="file.id">
            <div class="from-path">
              <el-icon><FolderOpened /></el-icon>
              <span>{{ file.parentPath || '根目录' }}/{{ file.fileName }}</span>
            </div>
            <div class="arrow">
              <el-icon><Right /></el-icon>
            </div>
            <div class="to-path">
              <el-icon><Folder /></el-icon>
              <span>{{ targetFolder.path }}/{{ file.fileName }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 冲突警告 -->
      <div v-if="conflicts.length > 0" class="conflicts-section">
        <el-alert
          title="检测到文件名冲突"
          type="warning"
          :closable="false"
          show-icon
        >
          <div class="conflict-list">
            <div v-for="conflict in conflicts" :key="conflict.fileName" class="conflict-item">
              <el-icon><Warning /></el-icon>
              <span>{{ conflict.fileName }} 在目标位置已存在</span>
            </div>
          </div>
        </el-alert>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">取消</el-button>
        <el-button
          type="primary"
          @click="handleMove"
          :loading="moving"
          :disabled="!canMove"
        >
          <el-icon><FolderRemove /></el-icon>
          移动 ({{ filesToMove.length }}个)
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Folder,
  Document,
  FolderOpened,
  FolderRemove,
  Right,
  Warning
} from '@element-plus/icons-vue'
import FolderSelector from './FolderSelector.vue'
import { moveFile, getFileList, type FileInfo } from '@/api/file'

// Props 和 Emits
interface Props {
  modelValue: boolean
  files: FileInfo[]
}

interface Emits {
  (e: 'update:modelValue', value: boolean): void
  (e: 'success'): void
}

// 移动选项接口
interface MoveOptions {
  keepOriginalPath: boolean
  overwriteExisting: boolean
}

// 冲突文件接口
interface ConflictFile {
  fileName: string
  type: 'file' | 'folder'
}

// 文件夹节点接口（与FolderSelector保持一致）
interface FolderNode {
  id: number
  label: string
  path: string
  parentId: number
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

// 响应式数据
const visible = ref(false)
const moving = ref(false)
const targetFolderId = ref(0)
const targetFolder = ref<FolderNode | null>(null)
const conflicts = ref<ConflictFile[]>([])

// 移动选项
const moveOptions = reactive<MoveOptions>({
  keepOriginalPath: false,
  overwriteExisting: false
})

// 计算属性
const filesToMove = computed(() => props.files || [])

// 排除的文件夹ID（防止移动到自身或子文件夹）
const excludeFolderIds = computed(() => {
  const ids: number[] = []

  // 排除待移动的文件夹本身
  filesToMove.value.forEach(file => {
    if (file.isFolder === 1) {
      ids.push(file.id)
    }
  })

  // 排除当前文件夹（如果所有文件都在同一个文件夹）
  const currentFolderIds = [...new Set(filesToMove.value.map(f => f.parentId))]
  if (currentFolderIds.length === 1 && currentFolderIds[0] !== undefined) {
    ids.push(currentFolderIds[0])
  }

  return ids
})

// 是否可以移动
const canMove = computed(() => {
  return (
    filesToMove.value.length > 0 &&
    targetFolder.value &&
    targetFolder.value.id !== filesToMove.value[0]?.parentId &&
    (conflicts.value.length === 0 || moveOptions.overwriteExisting)
  )
})

// 监听显示状态
watch(() => props.modelValue, (newVal) => {
  visible.value = newVal
  if (newVal) {
    resetForm()
    checkConflicts()
  }
})

watch(visible, (newVal) => {
  emit('update:modelValue', newVal)
})

// 监听目标文件夹变化
watch([targetFolderId, moveOptions], () => {
  checkConflicts()
}, { deep: true })

// 重置表单
const resetForm = () => {
  targetFolderId.value = 0
  targetFolder.value = null
  conflicts.value = []
  moveOptions.keepOriginalPath = false
  moveOptions.overwriteExisting = false
}

// 处理文件夹选择变化
const handleFolderChange = (folder: FolderNode | null) => {
  targetFolder.value = folder
}

// 检查文件名冲突
const checkConflicts = async () => {
  if (!targetFolder.value || filesToMove.value.length === 0) {
    conflicts.value = []
    return
  }

  try {
    // 获取目标文件夹中的文件列表
    const response = await getFileList({
      parentId: targetFolder.value.id,
      page: 1,
      size: 1000,
      orderBy: 'fileName',
      orderType: 'asc'
    })

    const existingFiles = response.content
    const conflictFiles: ConflictFile[] = []

    // 检查每个待移动文件是否与目标位置文件冲突
    filesToMove.value.forEach(file => {
      const existing = existingFiles.find(existing =>
        existing.fileName === file.fileName &&
        existing.isFolder === file.isFolder
      )

      if (existing) {
        conflictFiles.push({
          fileName: file.fileName,
          type: file.isFolder === 1 ? 'folder' : 'file'
        })
      }
    })

    conflicts.value = conflictFiles
  } catch (error) {
    // 获取目标文件夹文件列表失败，假设无冲突
    conflicts.value = []
  }
}

// 执行移动操作
const handleMove = async () => {
  if (!canMove.value) return

  try {
    // 如果有冲突且未选择覆盖，再次确认
    if (conflicts.value.length > 0 && !moveOptions.overwriteExisting) {
      ElMessage.warning('请处理文件名冲突或选择覆盖现有文件')
      return
    }

    // 最终确认
    const confirmText = conflicts.value.length > 0
      ? `确定要移动 ${filesToMove.value.length} 个文件到 "${targetFolder.value?.path}" 吗？\n\n⚠️ 将覆盖 ${conflicts.value.length} 个同名文件！`
      : `确定要移动 ${filesToMove.value.length} 个文件到 "${targetFolder.value?.path}" 吗？`

    await ElMessageBox.confirm(
      confirmText,
      '确认移动',
      {
        confirmButtonText: '确定移动',
        cancelButtonText: '取消',
        type: conflicts.value.length > 0 ? 'warning' : 'info',
        dangerouslyUseHTMLString: true
      }
    )

    moving.value = true

    // 逐个移动文件
    const results = []
    for (const file of filesToMove.value) {
      try {
        const result = await moveFile(file.id, targetFolder.value!.id)
        results.push({ file, success: true, result })
      } catch (error: any) {
        results.push({ file, success: false, error: error.message })
      }
    }

    // 统计结果
    const successCount = results.filter(r => r.success).length
    const failureCount = results.length - successCount

    if (failureCount === 0) {
      ElMessage.success(`成功移动 ${successCount} 个文件`)
    } else if (successCount === 0) {
      ElMessage.error(`移动失败：${results[0]?.error || '未知错误'}`)
    } else {
      ElMessage.warning(`移动完成：成功 ${successCount} 个，失败 ${failureCount} 个`)
    }

    // 如果有成功的移动，关闭对话框并通知父组件刷新
    if (successCount > 0) {
      visible.value = false
      emit('success')
    }

  } catch (error: any) {
    if (error !== 'cancel') {
      ElMessage.error(error.message || '移动失败')
    }
  } finally {
    moving.value = false
  }
}

// 格式化文件大小
const formatFileSize = (size: number): string => {
  if (size < 1024) return size + ' B'
  if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB'
  if (size < 1024 * 1024 * 1024) return (size / (1024 * 1024)).toFixed(2) + ' MB'
  return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB'
}

// 关闭对话框
const handleClose = () => {
  visible.value = false
}
</script>

<style scoped>
.move-dialog-content {
  display: flex;
  flex-direction: column;
  gap: 20px;
  max-height: 70vh;
  overflow-y: auto;
}

/* 文件列表区域 */
.files-section h4 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 14px;
}

.files-list {
  max-height: 120px;
  overflow-y: auto;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 8px;
}

.file-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
}

.file-icon {
  color: #409eff;
  flex-shrink: 0;
}

.file-name {
  flex: 1;
  font-size: 14px;
  color: #333;
}

.file-size {
  font-size: 12px;
  color: #999;
  flex-shrink: 0;
}

/* 目标位置区域 */
.target-section h4 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 14px;
}

/* 选项区域 */
.options-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 4px;
}

/* 预览区域 */
.preview-section h4 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 14px;
}

.move-preview {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
  background: #fafafa;
}

.preview-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid #eee;
}

.preview-item:last-child {
  border-bottom: none;
}

.from-path,
.to-path {
  display: flex;
  align-items: center;
  gap: 5px;
  flex: 1;
  font-size: 13px;
}

.from-path {
  color: #666;
}

.to-path {
  color: #409eff;
  font-weight: 500;
}

.arrow {
  color: #999;
  flex-shrink: 0;
}

/* 冲突警告区域 */
.conflicts-section {
  margin-top: 10px;
}

.conflict-list {
  margin-top: 10px;
}

.conflict-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  color: #e6a23c;
  font-size: 13px;
}

/* 对话框底部 */
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .move-dialog-content {
    max-height: 60vh;
  }

  .preview-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
  }

  .arrow {
    align-self: center;
    transform: rotate(90deg);
  }

  .from-path,
  .to-path {
    width: 100%;
  }
}

/* 滚动条样式 */
.files-list::-webkit-scrollbar,
.move-dialog-content::-webkit-scrollbar {
  width: 6px;
}

.files-list::-webkit-scrollbar-track,
.move-dialog-content::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 3px;
}

.files-list::-webkit-scrollbar-thumb,
.move-dialog-content::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.files-list::-webkit-scrollbar-thumb:hover,
.move-dialog-content::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}
</style>